package metagen;



import java.util.Random;

import main.MetaGen;

public class NRep implements MetaGen {

    private static final int MIN_REP = 0;
    private static final int MAX_REP = 16;

    private Random rand;
    private MetaGen meta;
    private int m;  // 0 means no lower limit
    private int n;  // 0 means no upper limit, m/n can't be both 0

    public NRep(MetaGen meta, int m, int n) {
        if (m <= 0 && n <= 0) {
            throw new RuntimeException("Invalid NRep meta generator: m, n can't be both 0");
        }
        if (m > 0 && n > 0 && m > n) {
            throw new RuntimeException("Invalid NRep meta generator: m must be less or equal to n");
        }
        if (m > MAX_REP || n > MAX_REP) {
            throw new RuntimeException("Invalid NRep meta generator: m, n must be less than " + MAX_REP);
        }
        if (meta == null) {
            throw new RuntimeException("Regexp to be repeated must be non-null!");
        }
        this.meta = meta;
        this.m = m;
        this.n = n;
        this.rand = new Random();
    }

    public String toString() {
        if (m <= 0) {
            return meta.toString() + "{," + n + "}";
        }
        if (n <= 0) {
            return meta.toString() + "{" + m + ",}";
        }
        return meta.toString() + "{" + m + "," + n + "}";
    }

    public String randGen() {
        StringBuilder sb = new StringBuilder();
        int range = ((n > 0) ? n : MAX_REP) - m + 1;
        int times = m + rand.nextInt(range);
        for (int i = 0; i < times; ++i) {
            sb.append(meta.randGen());
        }
        return sb.toString();
    }

    public void setMeta(MetaGen meta) {
        this.meta = meta;
    }

    public void setM(int m) {
        this.m = m;
    }

    public void setN(int n) {
        this.n = n;
    }
}
